/***********************************************/
/**			system_call.s by doom119		   */
/**				April, 2010					   */
/***********************************************/
EAX		=0X00
EBX		=0X04
ECX		=0X08
EDX		=0X0C
FS		=0X10
ES		=0X14
DS		=0X18
EIP		=0X1C
CS		=0X20
EFLAGS	=0X24
OLDESP	=0X28
OLDSS	=0X2C

state = 0
counter = 4

NR_SYSTEM_CALLS = 72

.global timer_interrupt, sys_fork, system_call, hd_interrupt
bad_system_call:
	movl $-1, %eax
	iret

reschedule:
	pushl ret_from_system_call
	jmp schedule

system_call:
	cmpl $NR_SYSTEM_CALLS-1, %eax
	ja bad_system_call
	push %ds
	push %es
	push %fs
#edx, ecx, ebx is the params of system calls, must be put in stack in order 
#according to the rule of GNU GCC
	pushl %edx
	pushl %ecx
	pushl %ebx
	movl $0x10, %edx
	mov %dx, %es
	mov %dx, %ds
	movl $0x17, %edx
	mov %dx, %fs
	call system_call_table(, %eax, 4)
# %eax is return value
	pushl %eax
	movl current, %eax
	cmpl $0, state(%eax)
	jne reschedule
	cmpl $0, counter(%eax)
	je reschedule

ret_from_system_call:
#remeber to tackle signal######################
	popl %eax
	popl %ebx
	popl %ecx
	popl %edx
	pop %fs
	pop %es
	pop %ds
	iret


timer_interrupt:
	push %ds
	push %es
	push %fs
	pushl %edx
	pushl %ecx
	pushl %ebx
	pushl %eax
	movl $0x10, %eax
	mov %ax, %ds
	mov %ax, %es
	movl $0x17, %eax
	mov %ax, %fs
	incl jiffies
	movl CS(%esp), %eax
	andl $3, %eax
	pushl %eax
	call do_timer
	addl $4, %esp
#to deal with signal
	jmp ret_from_system_call

sys_fork:
	call find_empty_process
	testl %eax, %eax
	js 1f
	push %gs
	pushl %esi
	pushl %edi
	pushl %ebp
	pushl %eax
	call copy_process
	addl $20, %esp
1:	ret

# int 46(IRQ14), interrupt of hard disk
hd_interrupt:
	pushl %eax
	pushl %ecx
	pushl %edx
	push %ds
	push %es
	push %fs
	movl $0x10, %eax
	mov %ax, %ds
	mov %ax, %es
	movl $0x17, %eax
	mov %ax, %fs
	xchgl do_hd, %edx
	testl %edx, %edx
	jne 1f
	movl $unexpected_hd_interrupt, %edx
1:	call *%edx
	pop %fs
	pop %es
	pop %dx
	popl %edx
	popl %ecx
	popl %eax
	iret
